package com.niiwoo.civet.trade.service.dubbo.loan.credit;


import com.alibaba.dubbo.config.annotation.Service;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProjectDynamic;
import com.niiwoo.civet.trade.dao.entity.credit.CreditProjectGuarantee;
import com.niiwoo.civet.trade.dao.mapper.credit.CreditProjectDynamicMapperExt;
import com.niiwoo.civet.trade.dao.mapper.credit.CreditProjectGuaranteeMapperExt;
import com.niiwoo.civet.trade.dto.CreditProjectDTO;
import com.niiwoo.civet.trade.dto.request.credit.CreditLoanGuaranteeProjectDetailRequestDTO;
import com.niiwoo.civet.trade.dto.request.credit.CreditLoanGuaranteeProjectRequestDTO;
import com.niiwoo.civet.trade.dto.request.credit.CreditLoanGuaranteeStatisticsRequestDTO;
import com.niiwoo.civet.trade.dto.request.loan.credit.INeedGuaranteeRequestDTO;
import com.niiwoo.civet.trade.dto.response.credit.CreditLoanGuaranteeProjectDetailDTO;
import com.niiwoo.civet.trade.dto.response.credit.CreditLoanGuaranteeProjectDetailResponseDTO;
import com.niiwoo.civet.trade.dto.response.credit.CreditLoanGuaranteeProjectResponseDTO;
import com.niiwoo.civet.trade.dto.response.credit.CreditLoanGuaranteeStatisticsResponseDTO;
import com.niiwoo.civet.trade.dto.response.loan.credit.INeedGuaranteeResponseDTO;
import com.niiwoo.civet.trade.enums.credit.CreditLoanGuaranteeProjectStatusEnum;
import com.niiwoo.civet.trade.service.loan.credit.CreditLoanDubboService;
import com.niiwoo.civet.trade.service.local.loan.credit.CreditLoanService;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * 信用借历史数据(数据迁移) dubbo服务实现
 *
 * @author liming
 * @date 2017-12-14 19:19
 */
@Slf4j
@Service(version = "1.0.0")
public class CreditLoanDubboServiceImpl implements CreditLoanDubboService {

    @Autowired
    private CreditLoanService creditLoanService;

    @Autowired
    private CreditProjectGuaranteeMapperExt creditProjectGuaranteeMapperExt;

    @Autowired
    private CreditProjectDynamicMapperExt creditProjectDynamicMapperExt;

    @Override
    public PageResponseDTO<INeedGuaranteeResponseDTO> pageINeedGuarantee(INeedGuaranteeRequestDTO iNeedGuaranteeRequestDTO) {
        return creditLoanService.pageINeedGuarantee(iNeedGuaranteeRequestDTO);
    }

    /**
     * 获取用户的信用借担保项目列表
     * @param requestDTO
     * @return
     */
    @Override
    public PageResponseDTO<CreditLoanGuaranteeProjectResponseDTO> myCreditLoanGuaranteeProjects(CreditLoanGuaranteeProjectRequestDTO requestDTO) {
        PageResponseDTO<CreditLoanGuaranteeProjectResponseDTO> pageResponseDTO = new PageResponseDTO<>();

        if(Objects.isNull(Optional.ofNullable(requestDTO).map(dto -> dto.getUserId()).orElse(null))) return pageResponseDTO;//用户未登录
        Integer totalGuarante = creditProjectGuaranteeMapperExt.totalCreditLoanGuaranteProjectNum(requestDTO.getUserId());//总记录数
        if(Optional.ofNullable(totalGuarante).map(m -> m.intValue()).orElse(0) <= 0) return pageResponseDTO;

//        List<CreditLoanGuaranteeProjectResponseDTO> projects = creditProjectGuaranteeMapperExt.queryGuaranteeProject(requestDTO.getUserId(),requestDTO.getPageSize());
        List<CreditProjectDTO> projects = creditProjectGuaranteeMapperExt.queryAllGuaranteeProject(requestDTO.getUserId(),requestDTO.getPageSize());

        List<CreditLoanGuaranteeProjectResponseDTO> list = new ArrayList<>();
        for (CreditProjectDTO dto : projects){
            if(dto.getIsAdvance() != null && dto.getIsAdvance().byteValue() == (byte)1 //已垫付
                    && dto.getProjectStatus() != null
                    && (dto.getProjectStatus().byteValue() == CreditLoanGuaranteeProjectStatusEnum.OVERDUE.getCode()
                    || dto.getProjectStatus().byteValue() == CreditLoanGuaranteeProjectStatusEnum.BAD_DEBT.getCode())){//借款人已逾期或者坏账,担保人已垫付
                dto.setProjectStatus(CreditLoanGuaranteeProjectStatusEnum.LOAN_SUCCESS.getCode());//bug修改 2018/03/29 设置状态为成标,前端转换显示状态为还款中
            }
            CreditLoanGuaranteeProjectResponseDTO responseDTO = new CreditLoanGuaranteeProjectResponseDTO();
            BeanUtils.copyProperties(dto,responseDTO);

            responseDTO.setExpectedReturn(dto.getRealProfit());//需求变更,担保预期收益改为担保实际收益,不包含担保服务费
            setSortFlag(responseDTO);
            list.add(responseDTO);
        }
        sort(list);
        // 返回分页数据
        pageResponseDTO.setTotalCount(totalGuarante);
        pageResponseDTO.measureTotalPage(pageResponseDTO.getTotalCount(),requestDTO.getPageSize());
        if(requestDTO.getPageNumber() > pageResponseDTO.getTotalPage()) return pageResponseDTO;
        int fromIndex = (requestDTO.getPageNumber() -1)*requestDTO.getPageSize();
        if(fromIndex > list.size()) return pageResponseDTO;
        int toIndex = fromIndex+requestDTO.getPageSize();
        if(toIndex > list.size()) toIndex = list.size();

        pageResponseDTO.setItems(list.subList(fromIndex,toIndex));
        return pageResponseDTO;
    }

    private void sort(List<CreditLoanGuaranteeProjectResponseDTO> list) {
        /*
         * 排序规则:按照还款中>逾期待垫付>已结清>流标、再按发布时间排序
         */
        Collections.sort(list, (o1, o2) -> o1.getSortFlag().byteValue() - o2.getSortFlag().byteValue() > 0 ? 1 :
                o1.getSortFlag().byteValue() == o2.getSortFlag().byteValue() ?
                        (o1.getPublishTime().before(o2.getPublishTime()) ? 1 : -1) : -1);
    }

    private void setSortFlag(CreditLoanGuaranteeProjectResponseDTO dto){
        CreditLoanGuaranteeProjectStatusEnum projectStatusEnum = CreditLoanGuaranteeProjectStatusEnum.enumOf(dto.getProjectStatus());
        switch (projectStatusEnum) {
            case LOAN_SUCCESS:
            case YELLOW_WARNING:
            case RED_WARNING:
                dto.setSortFlag(1);//还款中
                break;
            case LOAN:
            case GUARANTEE:
            case GUARANTEE_NOT_PASS:
            case LOAN_FAILURE:
            case LOAN_FAILURE_MANUAL:
                dto.setSortFlag(4);//流标
                break;
            case OVERDUE:
            case BAD_DEBT:
                /*
                 * 借款人逾期或者严重逾期时,无论担保人是否垫付逾期都展示(夏永)
                 */
                dto.setSortFlag(2);//逾期
                break;
            case REPAYMENT_FINISH:
            case BAD_DEBT_REPAYMENT_FINISH:
                dto.setSortFlag(3);//已结清
                break;
            default:
                break;
        }
    }


    /**
     * 获取用户信用借担保项目详情
     *
     * @param requestDTO
     * @return
     */
    @Override
    public CreditLoanGuaranteeProjectDetailResponseDTO creditLoanGuaranteeProjectDetail(CreditLoanGuaranteeProjectDetailRequestDTO requestDTO) {
        CreditLoanGuaranteeProjectDetailResponseDTO responseDTO = new CreditLoanGuaranteeProjectDetailResponseDTO();
        if(Optional.ofNullable(requestDTO).map(dto -> Objects.isNull(dto.getUserId()) || Objects.isNull(dto.getProjectId())).orElse(true))
            return responseDTO;
        responseDTO.setProjectId(requestDTO.getProjectId());
        responseDTO.setUserId(requestDTO.getUserId());

        List<CreditProjectGuarantee> guaranteeList = creditProjectGuaranteeMapperExt.queryCreditProjectGuarantee(requestDTO.getProjectId(),requestDTO.getUserId());
        if(CollectionUtils.isEmpty(guaranteeList)) return responseDTO;

        CreditProjectDynamic dynamic = new CreditProjectDynamic();
        dynamic.setProjectId(requestDTO.getProjectId());
        dynamic.setUserId(requestDTO.getUserId());
        dynamic.setType(2);//1借款相关 2担保相关 3投资相关 4还款相关（我的借款详情展示）
        List<CreditProjectDynamic> list = creditProjectDynamicMapperExt.queryCreditLoanGuaranteeProjectDetail(dynamic);
        List<CreditLoanGuaranteeProjectDetailDTO> details = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            for (CreditProjectDynamic creditProjectDynamic : list) {
                if(Objects.nonNull(creditProjectDynamic)){
                    CreditLoanGuaranteeProjectDetailDTO dto = new CreditLoanGuaranteeProjectDetailDTO();
                    dto.setDescription(creditProjectDynamic.getDescription());
                    dto.setCreateTime(creditProjectDynamic.getCreatetime());
                    details.add(dto);
                }else {
                    log.warn("+++++++++creditProjectDynamic为空+++++++++++");
                }
            }
        }

        responseDTO.setAdvanceAmount(guaranteeList.stream().map(CreditProjectGuarantee::getAdvanceAmount).reduce(BigDecimal.ZERO, BigDecimal::add));//应垫付金额
        responseDTO.setRealAdvanceAmount(guaranteeList.stream().map(CreditProjectGuarantee::getRealAdvanceAmount).reduce(BigDecimal.ZERO, BigDecimal::add));//实际垫付金额
        responseDTO.setIsAdvanceOverdue((byte)guaranteeList.stream().mapToInt(CreditProjectGuarantee::getIsAdvanceOverdue).max().getAsInt());//是否垫付逾期（0未逾期，1已逾期）
        responseDTO.setOverdueFine(guaranteeList.stream().map(CreditProjectGuarantee::getOverdueFine).reduce(BigDecimal.ZERO, BigDecimal::add));//当前需缴纳滞纳金
        responseDTO.setTotalOverdueFine(guaranteeList.stream().map(CreditProjectGuarantee::getTotalOverdueFine).reduce(BigDecimal.ZERO, BigDecimal::add));//累计应缴纳滞纳金
        responseDTO.setDetails(details);
        return responseDTO;
    }

    /**
     * 获取用户的担保项目统计信息
     *
     * @param requestDTO
     * @return
     */
    @Override
    public CreditLoanGuaranteeStatisticsResponseDTO creditLoanGuaranteeStatistics(CreditLoanGuaranteeStatisticsRequestDTO requestDTO) {
        CreditLoanGuaranteeStatisticsResponseDTO responseDTO =  new CreditLoanGuaranteeStatisticsResponseDTO(BigDecimal.ZERO,BigDecimal.ZERO,0);
        if(Optional.ofNullable(requestDTO).map(dto -> Objects.isNull(dto.getUserId())).orElse(true))
            return responseDTO;
        CreditLoanGuaranteeStatisticsResponseDTO result = creditProjectGuaranteeMapperExt.countCreditLoanGuarantee(requestDTO.getUserId());
        if(Objects.isNull(result)) return responseDTO;
        if(!Objects.isNull(result.getTotalGuaranteeFee())) responseDTO.setTotalGuaranteeFee(result.getTotalGuaranteeFee());
        if(!Objects.isNull(result.getTotalGuaranteeIncome())) responseDTO.setTotalGuaranteeIncome(result.getTotalGuaranteeIncome());
        if(!Objects.isNull(result.getTotalGuaranteeNum())) responseDTO.setTotalGuaranteeNum(result.getTotalGuaranteeNum());
        return responseDTO;
    }

}
